/**
 * Created by liumin on 14-5-6.
 */

var fs = require("fs");
var path = require("path");
var rimraf = require("rimraf");
var moment = require('moment');
var async = require("async");
var CommonUtil = require('./CommonUtil');

export = FileUtil;
class FileUtil
{
    // cursively make dir
    public static  mkdirs(p, mode, f?, made?) {
        if (typeof mode === 'function' || mode === undefined) {
            f = mode;
            mode = 0777 & (~process.umask());
        }
        if (!made)
            made = null;

        var cb = f || function () {};
        if (typeof mode === 'string')
            mode = parseInt(mode, 8);
        p = path.resolve(p);

        fs.mkdir(p, mode, function (er) {
            if (!er) {
                made = made || p;
                return cb(null, made);
            }
            switch (er.code) {
                case 'ENOENT':
                    FileUtil.mkdirs(path.dirname(p), mode, function (er, made) {
                        if (er) {
                            cb(er, made);
                        } else {
                            FileUtil.mkdirs(p, mode, cb, made);
                        }
                    });
                    break;

                // In the case of any other error, just see if there's a dir
                // there already.  If so, then hooray!  If not, then something
                // is borked.
                default:
                    fs.stat(p, function (er2, stat) {
                        // if the stat fails, then that's super weird.
                        // let the original error be the failure reason.
                        if (er2 || !stat.isDirectory()) {
                            cb(er, made);
                        } else {
                            cb(null, made)
                        };
                    });
                    break;
            }
        });
    }

    public static rmdir(dir, callback) {
        if (fs.existsSync(dir)){
            rimraf(dir,callback);
            console.log("[FileUtil] del dir: "+dir);
        } else {
            callback(null);
        }
    }

    public static rmdirBefore(dir,daysAgo,callback){
        var now = Number(moment(new Date()).subtract(daysAgo,'days').format('YYYYMMDD'));
        if (fs.existsSync(dir)){
            FileUtil.deldirBefore(dir,now,callback);
        } else {
            callback(null);
        }
    }

    // 删除dir中创建时间在datetime(eg:20160125)之前的子文件(夹)
    private static deldirBefore(dir, datetime, callback){
        fs.readdir(dir, function(error,files){
            if(error){
                callback(error);
                return;
            }

            files.forEach(function(file){
                var curPath = dir+"/"+file;
                fs.lstat(curPath, function(err, stat){
                    if (err){
                        callback(err);
                        return;
                    }
                    var createtime = Number(moment(stat.birthtime).format('YYYYMMDD'));
                    if (stat.isDirectory()) {
                        if (fs.existsSync(curPath)){
                            if (createtime < datetime){
                                FileUtil.rmdir(curPath, callback);
                            } else {
                                FileUtil.deldirBefore(curPath, datetime, callback);
                            }
                        }

                    } else {
                        if (createtime < datetime && fs.existsSync(curPath)){
                            console.log("[FileUtil] del file: "+curPath);
                            fs.unlink(curPath,callback);
                        }
                    }
                });
            });
        });
    }
    /**
     * 功能：清除图片服务器image下载缓存文件
     * 注意：1、图片服务器的redis的ttl为30天，可以删除三个月以前的文件夹
     *      2、要求文件夹结构如下：
     *            2016----01
     *                  |
     *                  --02
     *                  |
     *                  --03
     *                  |
     *                  ......
     *
     *            2017----01
     *                  |
     *                  --02
     *                  |
     *                  --03
     *                  |
     *                  ......
     *
     * 接口名称:delDownloadDirBeforeByName
     * 参数：dir，图像下载文件夹，按年月日生成文件夹，形如: /mnt/
     * 参数：callback,参数如下：
     *      error:
     *      cleanDirs:
     */
    public static delDownloadDirBeforeByName(dir,callback){
        var limit = CommonUtil.genDayStr(-31,'YYYY/MM');// 删除31天之前的月份 //删除60天之前的月份
        var years = fs.readdirSync(dir);
        var delList  = []; // 待删除列表
        if(years){
            for(var i=0;i<years.length;i++){
                var year = years[i];
                if(fs.existsSync(dir+ year)){
                    var stat = fs.statSync(dir+year);
                    if(stat && stat.isDirectory()){
                        var months = fs.readdirSync(dir+ year);
                        if(months){
                            for(var j=0;j<months.length;j++){
                                var month = months[j];
                                var monthStr = year+'/'+month;
                                if(monthStr<limit){
                                    // 纪录之
                                    delList.push(dir+monthStr);
                                }
                            }
                        }
                    }

                }

            }
        }

        var asyncFuncs = [];
        for(var i=0;i<delList.length;i++){
            asyncFuncs.push((function (filePath,index) {
                return function (asyncCallback) {
                    rimraf(filePath,function(error){
                        if(error){
                            console.log('******* clean image download cache error in rimraf:'+error);
                        }
                        asyncCallback(null, null);
                    });



                };
            })(delList[i],i)); // 利用闭包解决动态参数传递问题
        }

        async.parallelLimit(asyncFuncs,5, function (error, results) {
            if(error){
                console.log('******* clean image download cache error in async.parallelLimit:'+error);
            }
            callback(null, delList.length);
        });
    }

};
